﻿using DAL;
using IService;
using Microsoft.EntityFrameworkCore;
using Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Service
{
    public class WhInventoryService : IWhInventoryService
    {
        private readonly WhInventoryDal dal;
        private readonly AppDbContext _dbContext;
        public WhInventoryService(WhInventoryDal dal, AppDbContext dbContext)
        {
            this.dal = dal;
            _dbContext = dbContext;
        }

        public Task<int> CreateAsync(WhInventory data)
        {
            return dal.CreateAsync(data);
        }

        public Task<int> DeleteAsync(int Id)
        {
            return dal.DeleteAsync(Id);
        }

        public Task<List<WhInventory>> GetAllAsync()
        {
            return dal.GetAllAsync();
        }

        public Task<WhInventory> GetByIdAsync(int Id)
        {
            return dal.GetByIdAsync(Id);
        }

        public Task<int> UpdateAsync(WhInventory date)
        {
            return dal.UpdateAsync(date);
        }

        public async Task<List<InventoryAggregateDTO>> GetInventoryAggregateListAsync()
        {
            return await dal.GetInventoryAggregateListAsync();
        }

        public async Task<List<WarehouseLocationGoodsDTO>> GetGoodsByWarehouseAndLocationAsync(long warehouseId, long storageLocationId)
        {
            if (warehouseId <= 0 || storageLocationId <= 0)
                throw new ArgumentException("仓库ID和库位ID不能为空");

            return await dal.GetGoodsByWarehouseAndLocationAsync(warehouseId, storageLocationId);
        }

        public Task<decimal> GetBookInventoryAsync(long warehouseId, long goodsId, long storageLocationId)
        {
            return dal.GetBookInventoryAsync(warehouseId, goodsId, storageLocationId);
        }

        /// <summary>
        /// 盘点审核通过后调整库存（盘盈入库、盘亏出库）
        /// </summary>
        public async Task<int> AdjustInventoryForStockTakeAsync(long inventoryOrderId)
        {
            // 移除服务层的事务，由控制器层统一管理事务
            try
            {
                // 1. 打印盘点单ID，确认方法被调用
                Console.WriteLine($"开始调整库存，盘点单ID：{inventoryOrderId}");

                var stockTake = await _dbContext.WhStockTake.FirstOrDefaultAsync(st => st.InventoryOrderId == inventoryOrderId);
                if (stockTake == null)
                    throw new KeyNotFoundException($"盘点单ID：{inventoryOrderId} 不存在");

                long warehouseId = stockTake.WarehouseId;
                var stockTakeDetails = await _dbContext.WhStockTakeDetail
                    .Where(d => d.InventoryOrderId == inventoryOrderId && d.IsDelete != "Y")
                    .ToListAsync();

                // 2. 打印明细数量，确认有数据可处理
                Console.WriteLine($"盘点明细数量：{stockTakeDetails.Count}");

                var goodsCodes = stockTakeDetails.Select(d => d.GoodsCode).Distinct().ToList();
                var goodsMap = await _dbContext.BiProduct
                    .Where(p => goodsCodes.Contains(p.GoodsCode))
                    .ToDictionaryAsync(p => p.GoodsCode, p => p.GoodsId);

                int updateCount = 0;
                foreach (var detail in stockTakeDetails)
                {
                    if (!goodsMap.TryGetValue(detail.GoodsCode, out long goodsId))
                        throw new KeyNotFoundException($"货品Code：{detail.GoodsCode} 未找到对应货品");

                    long storageLocationId = detail.StorageLocationId;
                    decimal profitLossQty = detail.ProfitLossQuantity;

                    // 3. 打印每条明细的调整条件
                    Console.WriteLine($"调整条件：warehouseId={warehouseId}, storageLocationId={storageLocationId}, goodsId={goodsId}, 调整量={profitLossQty}");

                    // 关键修复：如果库存记录不存在，创建新的库存记录
                    var inventory = await GetByCompositeKeyAsync(warehouseId, storageLocationId, goodsId);
                    if (inventory == null)
                    {
                        // 创建新的库存记录
                        Console.WriteLine($"创建新的库存记录：仓库ID={warehouseId}，库位ID={storageLocationId}，货品ID={goodsId}");

                        inventory = new WhInventory
                        {
                            WarehouseId = warehouseId,
                            StorageLocationId = storageLocationId,
                            GoodsId = goodsId,
                            AvailableInventoryQty = profitLossQty > 0 ? profitLossQty : 0, // 盘盈时设置初始库存，盘亏时不创建负库存
                        };

                        _dbContext.WhInventory.Add(inventory);
                        updateCount++;
                        Console.WriteLine($"创建新库存记录，初始数量：{inventory.AvailableInventoryQty}");
                    }
                    else
                    {
                        // 4. 打印调整前的库存数量
                        Console.WriteLine($"调整前库存：{inventory.AvailableInventoryQty}");

                        // 关键修复：根据盘盈盘亏调整库存
                        // profitLossQty > 0 表示盘盈（需要增加库存）
                        // profitLossQty < 0 表示盘亏（需要减少库存）
                        inventory.AvailableInventoryQty += profitLossQty;

                        // 确保库存数量不会为负数
                        if (inventory.AvailableInventoryQty < 0)
                        {
                            Console.WriteLine($"警告：调整后库存为负数({inventory.AvailableInventoryQty})，自动调整为0");
                            inventory.AvailableInventoryQty = 0;
                        }

                        //inventory.UpdateTime = DateTime.Now;
                        updateCount++;

                        // 5. 打印调整后的库存数量
                        Console.WriteLine($"调整后库存：{inventory.AvailableInventoryQty}");
                    }
                }

                // 一次性保存所有更改
                await _dbContext.SaveChangesAsync();
                Console.WriteLine($"库存调整完成，共更新{updateCount}条记录");
                return updateCount;
            }
            catch (Exception ex)
            {
                Console.WriteLine($"库存调整异常：{ex.Message}\n堆栈：{ex.StackTrace}");
                throw;
            }
        }

        /// <summary>
        /// 根据复合主键查询库存记录（关键修复）
        /// </summary>
        private async Task<WhInventory> GetInventoryByCompositeKeyAsync(long warehouseId, long storageLocationId, long goodsId)
        {
            return await _dbContext.WhInventory
                .FirstOrDefaultAsync(inv =>
                    inv.WarehouseId == warehouseId &&
                    inv.StorageLocationId == storageLocationId &&
                    inv.GoodsId == goodsId);
        }
        public Task<WhInventory> GetByCompositeKeyAsync(long warehouseId, long storageLocationId, long goodsId)
        {
            return dal.GetByCompositeKeyAsync(warehouseId, storageLocationId, goodsId);
        }
    }
}
